﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Algobox.JuicyLib.SQL.LiquidView;

namespace LiquidTrading.LiquidViewSyncTool
{
    public class ProcessChix
    {
        const int SYMBOL_NUM_COL = 15;
        const int TICK_NUM_COL = 4;

        const char SEPERATOR_ROW = '\n';
        const char SEPERATOR_COL = '|';

        const int SYMBOL_PRI_NAME = 2;
        const int SYMBOL_PRI_RIC = 3;
        const int SYMBOL_PRI_BBG = 4;
        const int SYMBOL_PRI_ISIN = 5;
        const int SYMBOL_PRI_MIC = 7;
        const int SYMBOL_PRI_UMTF = 10;
        const int SYMBOL_PRI_IDX = 11;

        const int SYMBOL_LOC_SYM = 1;
        const int SYMBOL_LOC_CCY = 6;
        const int SYMBOL_LOC_RIC = 8;
        const int SYMBOL_LOC_BBG = 9;
        const int SYMBOL_LOC_TICK = 13;

        const int TICK_NAME = 1;
        const int TICK_MIN = 2;
        const int TICK_SIZE = 3;

       


        public static void ProcessSymbols(LiquidViewLinqDataContext linq, ref string symbols)
        {
            string[] rows = symbols.Split(SEPERATOR_ROW);
            string[] data;

            string currency;

            int end = rows.Length - 2;

            for (int start = 1; start < end; start++)
            {
                data = rows[start].Trim().Split(SEPERATOR_COL);

                if (data.Length != SYMBOL_NUM_COL)
                {
                    string message = "File failure wrong number of columns (possibly and extra ',') - " + rows[start];
                    linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Symbols - " + message, null);
                }
                else
                {
                    // update InstrumentStock               
                    currency = data[SYMBOL_LOC_CCY];
                    if (currency == "GBp" || currency == "GBX")
                        currency = "GBP";

                    string market = Program.CompareTheMeerkat(data[SYMBOL_PRI_MIC]);

                    string index = data[SYMBOL_PRI_IDX].Replace(" ", "");

                    int? stockId = null;

                    // inport instrument stock
                    /*
                    int result = linq.ImportInstrumentStock(
                        data[SYMBOL_PRI_MIC],
                        currency,
                        data[SYMBOL_PRI_ISIN],
                        null,
                        data[SYMBOL_PRI_UMTF],
                        data[SYMBOL_PRI_UMTF],
                        data[SYMBOL_PRI_NAME],
                        null,
                        index,
                        data[SYMBOL_PRI_BBG],
                        data[SYMBOL_PRI_RIC],
                        null,
                        false,
                        ref stockId);
                    */
                    int result = linq.ImportInstrumentStockByUMTF(
                        data[SYMBOL_PRI_UMTF],
                        market,
                        currency,
                        data[SYMBOL_PRI_ISIN],
                        null,                        
                        data[SYMBOL_PRI_NAME],
                        null,
                        index,
                        data[SYMBOL_PRI_BBG],
                        data[SYMBOL_PRI_RIC],
                        null,
                        false,
                        ref stockId);


                    if (result == 0)
                    {
                        Console.WriteLine("Created " + data[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "New Chi-X stock " + data[SYMBOL_PRI_UMTF] + " created", null);
                    }
                    else if (result == 1)
                    {
                        //Console.WriteLine("Updated...");
                    }
                    else if (result == 2)
                    {
                        Console.WriteLine("Changed MarketMIC for " + data[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "WARNING: Market changed for " + data[SYMBOL_PRI_UMTF], null);
                    }
                    else if (result == 3)
                    {
                        Console.WriteLine("Changed Currency for " + data[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "WARNING: Currency changed for " + data[SYMBOL_PRI_UMTF], null);
                    }
                    else if (result == 4)
                    {
                        Console.WriteLine("Created " + data[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "WARNING: Market and Currency changed for " + data[SYMBOL_PRI_UMTF], null);
                    }
                    else if (result < 0)
                    {
                        if (result == -1)
                        {
                            string message = "General failure processing " + data[SYMBOL_PRI_UMTF];
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Symbols - " + message, null);
                        }
                        else if (result == -2)
                        {
                            string message = "MarketMIC failure processing " + data[SYMBOL_PRI_UMTF] + " with " + market;
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Symbols - " + message, null);
                        }
                        else if (result == -3)
                        {
                            string message = "Currency failure processing " + data[SYMBOL_PRI_UMTF] + " with " + currency;
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Symbols - " + message, null);
                        }
                        else if (result == -4)
                        {
                            string message = "Index failure processing " + data[SYMBOL_PRI_UMTF] + " with " + index;
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Symbols - " + message, null);
                        }
                        else
                        {
                            string message = "Some other failure processing failure processing " + data[SYMBOL_PRI_UMTF];
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Symbols - " + message, null);
                        }
                    }
                    else
                    {
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Symbols - Unknown return value on ImportInstrumentStock", null);
                    }


                    int? listingId = null;


                    // check for Chi-X fixed tick size
                    decimal tickValue;
                    if (Decimal.TryParse(data[SYMBOL_LOC_TICK], out tickValue) && tickValue != 0)
                    {
                        long? tickSizeId = null;
                        linq.ImportTickSize(data[SYMBOL_LOC_TICK], "CHIX", null, tickValue, ref tickSizeId);
                    }

                    currency = data[SYMBOL_LOC_CCY];
                    if (currency == "GBp")
                        currency = "GBX";

                    // inport instrument stock listing
                    result = linq.ImportInstrumentStockListing(
                        stockId,
                        "CHIX",
                        currency,
                        data[SYMBOL_LOC_TICK],
                        data[SYMBOL_PRI_UMTF],
                        data[SYMBOL_LOC_BBG],
                        data[SYMBOL_LOC_RIC],
                        ref listingId);

                    if (result == 0)
                    {
                        Console.WriteLine("Created Stock Listing for " + data[SYMBOL_PRI_UMTF]);
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "New Chi-X Stock Listing " + data[SYMBOL_PRI_UMTF] + " created", null);
                    }
                    else if (result == 1)
                    {
                        //Console.WriteLine("Updated...");
                    }
                    else if (result == -1)
                    {
                        string message = "General failure processing " + data[SYMBOL_PRI_UMTF];
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Stock Listing - " + message, null);
                    }
                    else if (result == -2)
                    {
                        string message = "ExchangMIC failure processing CHIX";
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Stock Listing - " + message, null);
                    }
                    else if (result == -3)
                    {
                        string message = "StockId failure processing " + stockId;
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Stock Listing - " + message, null);
                    }
                    else if (result == -4)
                    {
                        string message = "Tick range failure processing " + data[SYMBOL_PRI_UMTF] + " with " + data[SYMBOL_LOC_TICK];
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Stock Listing - " + message, null);

                    }
                    else
                    {
                        linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Stock Listing - Unknown return value on ImportInstrumentStock", null);
                    }

                }

            }

        }



        public static bool ProcessTicks(LiquidViewLinqDataContext linq, ref string ticks)
        {
            string[] rows = ticks.Split(SEPERATOR_ROW);
            string[] data;

            Dictionary<decimal, decimal> pair;
            Dictionary<string, Dictionary<decimal, decimal>> ranges = new Dictionary<string, Dictionary<decimal, decimal>>();

            decimal min;
            decimal size;
            string name;

            int end = rows.Length - 2;

            for (int start = 1; start < end; start++)
            {
                data = rows[start].Trim().Split(SEPERATOR_COL);

                name = data[TICK_NAME];

                if (!Decimal.TryParse(data[TICK_MIN], out min))
                    linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Ticks - Couldn't decode TICK_MIN " + data[TICK_MIN], null);

                if (!Decimal.TryParse(data[TICK_SIZE], out size))
                    linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Ticks - Couldn't decode TICK_SIZE " + data[TICK_SIZE], null);

                if (!ranges.TryGetValue(name, out pair))
                {
                    pair = new Dictionary<decimal, decimal>();
                    ranges.Add(name, pair);
                }
                ranges[name].Add(min, size);
            }

            long? tickSizeId = null;

            // insert non dynamic - or fixed - tick sizes
            foreach (string tickName in ranges.Where(a => a.Value.Count == 1).Select(a => a.Key))
            {
                foreach (KeyValuePair<decimal, decimal> range in ranges[tickName])
                {
                    linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X Tick Range - Found an invalid single entry in ticks file for " + tickName + " " + range.Key + ":" + range.Value, null);
                }
            }


            //insert dynamic tick sizes
            foreach (string tickName in ranges.Where(a => a.Value.Count > 1).Select(a => a.Key))
            {
                foreach (KeyValuePair<decimal, decimal> range in ranges[tickName])
                {
                    int result = linq.ImportTickSize(tickName.Trim(), "CHIX", range.Key, range.Value, ref tickSizeId);

                    if (result != 4)
                    {
                        if (result == 0)
                        {
                            Console.WriteLine("Created " + tickName);
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "New Chi-X dynamic Tick Range " + tickName + " created", null);
                        }
                        else if (result == 1)
                        {
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Added new Chi-X dynamic Tick Range to " + tickName + " " + range.Key + ":" + range.Value, null);
                        }
                        else if (result == 2)
                        {
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Changed Chi-X Tick Range type from fixed to dynamic for " + tickName, null);
                        }
                        else if (result == -1)
                        {
                            string message = "General failure processing " + tickName;
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X dynamic Tick Range - " + message, null);
                        }
                        else if (result == -2)
                        {
                            string message = "ExchangeMIC failure processing " + tickName + " with fixed value of " + range.Value;
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X dynamic Tick Range - " + message, null);
                        }
                        else
                        {
                            linq.ExceptionHandlerThrow("LiquidViewSyncTool", "Chi-X dynamic Tick Range - Unknown return value on ImportTickSize", null);
                        }
                    }
                }
            }


            return true;
        }



    }
}
